Passed
Push — master ( 09e925...22dcc1 )
by Plamen
01:28
created

table.js ➔ TableHelperBuildRequest_Sort   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 24
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 17
nc 4
nop 2
dl 0
loc 24
rs 9.0833
c 0
b 0
f 0
1
var TableInitSetColumnsHoverEffect = function(tContainer, tableId){
2
    var tHcells = tContainer.rows[0].cells;
3
    for(var i = 0; i < tHcells.length; i++){
4
        if(tHcells[i].firstChild.tagName === "A"){
5
            tHcells[i].firstChild.setAttribute("onmouseover", "table.ColumnHover('" + tableId + "'," + i + ");");
6
            tHcells[i].firstChild.setAttribute("onmouseout", "table.ColumnHover('" + tableId + "');");
7
        }
8
    }
9
};
10
var TableHelperBuildRequest = function(rq, crntTableId, strDesc){
11
    rq.tableId = crntTableId;
12
    Sort(rq, strDesc);
13
    Filter(rq);
14
    function Sort(rq, strDesc){
15
        function sortBySpan(span, i){
16
            var order = span.innerHTML;
17
            if(order.length === 1){
18
                rq.colNo = i;
19
                rq.colOrd = order === strDesc ? "desc" : "asc";
20
            }
21
            return rq.colNo === i;
22
        }
23
24
        var thTags = document.getElementById(rq.tableId)
25
                .getElementsByTagName("thead")[0]
26
                .getElementsByTagName("th");
27
        var length = thTags.length;
28
        for(var i = 0; i < length; i++){
29
            var link = thTags[i].getElementsByTagName("a")[0];
30
            if(link){
31
                var span = link.getElementsByTagName("span")[0];
32
                if(span && sortBySpan(span, i)){
33
                    break;
34
                }
35
            }
36
        }
37
    };
38
    function Filter(rq){
39
        function getFilterFieldsByTableID(tableID){
40
            var fields = {filterBy: null, filter: null};
41
            var filterDiv = getFilterDivByTableIDOrNull(tableID);
42
            if(filterDiv !== null){
43
                setFilterBy(fields, filterDiv);
44
                setFilterValue(fields, filterDiv);
45
            }
46
            return fields;
47
        }
48
        function getFilterDivByTableIDOrNull(tableID){
49
            var res = null;
50
            if(document.getElementById(tableID).parentNode.getElementsByTagName("div").length > 0){
51
                for(var i = 0; i < document.getElementById(tableID).parentNode.getElementsByTagName("div").length; i++){
52
                    if(document.getElementById(tableID).parentNode.getElementsByTagName("div")[i].getAttribute("class") === "filter"){
53
                        return document.getElementById(tableID).parentNode.getElementsByTagName("div")[i];
54
                    }
55
                }
56
57
            }
58
            return res;
59
        }
60
        function setFilterBy(fields, filterDiv){
61
            var slctObj = filterDiv.getElementsByTagName("select")[0];
62
            if(slctObj && slctObj.options[slctObj.selectedIndex].value !== "all"){
63
                fields.filterBy = slctObj.options[slctObj.selectedIndex].value;
64
            }
65
        }
66
        function setFilterValue(fields, filterDiv){
67
            var textObj = filterDiv.getElementsByTagName("input")[0];
68
            if(textObj && textObj.value && textObj.value.length !== 0){
69
                fields.filter = encodeURIComponent(textObj.value.trim());
70
            }
71
        }
72
73
        var r = getFilterFieldsByTableID(rq.tableId);
74
        if(r.filter !== null){
75
            rq.filter = r.filter;
76
        }
77
        if(r.filterBy !== null){
78
            rq.filterBy = r.filterBy;
79
        }
80
    };
81
};
82
var TableHelperColumnHover = function(tableContainer, index){
83
    var rows = document.getElementById(tableContainer).rows;
84
    var upto = rows.length - 1;
85
    if(typeof index === "undefined"){
86
        TableHelperColumnHoverRelease(rows, upto);
87
    } else {
88
        for(var i = 0; i < upto; i++){
89
            rows[i].cells[index].setAttribute("lang", "col-hover");
90
        }
91
    }
92
};
93
var TableHelperColumnHoverRelease = function(rows, upto){
94
    for(var i = 0; i < upto; i++){
95
        for(var j = 0; j < rows[i].cells.length; j++){
96
            if(rows[i].cells[j].lang){
97
                rows[i].cells[j].removeAttribute("lang");
98
            }
99
        }
100
    }
101
};
102
var TableHelperSetVisability = function(tableContainer, flag){
103
    var tbl = document.getElementById(tableContainer);
104
    if(flag === true){
105
        tbl.style.filter = "none";
106
        tbl.style.opacity = "1";
107
        tbl.style.cursor = "auto";
108
    }else if(flag === false){
109
        tbl.style.filter = "blur(1px)";
110
        tbl.style.opacity = "0.8";
111
        tbl.style.cursor = "wait";
112
    }else{
113
        console.error("table error in the flag value");
114
    }
115
};
116
var TableHelperProcessPaginationLinks = function(tfoot){
117
    var pLinks = tfoot.querySelectorAll(".paging a");
118
    if(pLinks.length > 0){
119
        for(var j = 0; j < pLinks.length; j++){
120
            pLinks[j].setAttribute("href", "javascript:void(0);");
121
            pLinks[j].setAttribute("onclick", "return table.GoPage(this);");
122
        }
123
    }
124
};
125
var TableHelperGoPageGetNo = function(lnk, tableId){
126
    //check & serve pagination jump links
127
    var jumpDir = lnk.innerHTML.trim().substr(0, 1);
128
    if(jumpDir === "+" || jumpDir === "-"){
129
        var current = document.getElementById(tableId)
130
                        .querySelector("tfoot .paging .a").innerHTML;
131
        var jump = lnk.innerHTML.replace("K", "000").replace("M", "000000000");
132
        var jumpPage = (parseInt(current) + parseInt(jump));
133
        lnk.parentNode.setAttribute("data-page", jumpPage);
134
        lnk.style.transform = "none";
135
    }
136
    return lnk.parentNode.hasAttribute("data-page") ?
137
            lnk.parentNode.getAttribute("data-page") :
138
            lnk.innerHTML;
139
};
140
var TableHelperIePrior = function(v){
141
    var rv = false;
142
    if(window.navigator.appName === 'Microsoft Internet Explorer'){
143
        var ua = window.navigator.userAgent;
144
        var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
145
        if(re.exec(ua) !== null){
146
            rv = parseFloat(RegExp.$1);
147
        }
148
        rv = rv < v ? true : false;
149
    }
150
    return rv;
151
};
152
var TableHelperRequestToUrl = function(rq){
153
    var url = location.pathname + ".json" + location.search;
154
    if(typeof rq === "object"){
155
        var getUrlVarName = {
156
            colNo: "col", colOrd: "ord", filter: "filter",
157
            filterBy: "filter-by", pageNo: "pg", exportType: "export",
158
            tableId: "table-id"
159
        };
160
        var flagFirst = location.search.length < 1 ? true : false;
161
        for(var r in rq){
1 ignored issue
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
162
            var clue = flagFirst === true ? "?" : "&";
163
            url += clue + getUrlVarName[r] + "=" + rq[r];
164
            flagFirst = false;
165
        }
166
    }
167
    return url;
168
};
169
var TableHelperGetParent = function(obj, objType){
170
    while(obj && obj.tagName !== objType.toUpperCase()){
171
        obj = obj.parentNode;
172
    }
173
    return obj;
174
};
175
var TableHelperFilterGetTableId = function(field){
176
    if(field.tagName.toLowerCase() !== "select"){
177
        return field.getAttribute("data-table-id");
178
    }
179
    var f = field.parentNode.parentNode.getElementsByTagName("input")[0];
180
    return '' === f.value ? null : f.getAttribute("data-table-id");
181
};
182
var TableHelperDraw_Section = function(tableContainer, dt, tSection){
183
    var section = tSection === "tfoot" ? "tfoot" : "tbody";
184
    var tSec = document.getElementById(tableContainer)
185
                .getElementsByTagName(section)[0];
186
    TableHelperDraw_SectionClear(tSec, TableHelperIePrior(9));
187
    for(var i = 0; i < dt.length; i++){
188
        var row = dt[i];
189
        var tRow = document.createElement("tr");
190
        TableHelperDraw_SectionRow(row, tRow);
191
        tSec.appendChild(tRow);
192
        if(section === "tfoot"){
193
            TableHelperProcessPaginationLinks(tSec);
194
        }
195
    }
196
};
197
var TableHelperDraw_SectionClear = function(tSection, iePrior9){
198
    if(iePrior9){
199
        if(tSection.firstChild){
200
            while(tSection.firstChild){
201
                tSection.removeChild(tSection.firstChild);
202
            }
203
        }
204
    }else{
205
        tSection.innerHTML = "";
206
    }
207
};
208
var TableHelperDraw_SectionRow = function(row, tRow){
209
    for(var cell in row){
1 ignored issue
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
210
        var tCell = document.createElement("td");
211
        if(typeof row[cell] === "string" || typeof row[cell] === "number"){
212
            tCell.innerHTML = row[cell];
213
        }else if(typeof row[cell] === "object"){
214
            TableHelperDraw_SectionRowCellFromObject(row, cell, tCell);
215
        }
216
        tRow.appendChild(tCell);
217
    }
218
};
219
var TableHelperDraw_SectionRowCellFromObject = function(row, cell, tCell){
220
    for(var attr in row[cell]){
1 ignored issue
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
221
        if(typeof row[cell][attr] === "string"){
222
            tCell.innerHTML = row[cell][attr];
223
        }else if(typeof row[cell][attr] === "object"){
224
            for(var v in row[cell][attr]){
1 ignored issue
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
225
                tCell.setAttribute(v, row[cell][attr][v]);
226
            }
227
        }
228
    }
229
};
230
231
//https://addyosmani.com/resources/essentialjsdesignpatterns/book/#singletonpatternjavascript
232
var TableSingleton = (function(){
233
    // Instance stores a reference to the Singleton
234
    var instance;
235
    function initInstance(){
236
        // Singleton
237
        // Private methods and variables
238
        var tail = null;
239
        function LoadData(tableContainer, rq){
240
            if(tail!==null){ tail.abort();}
241
            TableHelperSetVisability(tableContainer, false);
242
            var xmlhttp = window.XMLHttpRequest ? 
243
                            new XMLHttpRequest() : /* code for IE7+, Firefox, Chrome, Opera, Safari */
244
                            new window.ActiveXObject("Microsoft.XMLHTTP");/*code for IE6, IE5 */
245
            xmlhttp.onreadystatechange = function(){
246
                if(xmlhttp.readyState === 4 && xmlhttp.status === 200){
247
                    Draw(tableContainer, JSON.parse(xmlhttp.responseText));
248
                    TableHelperSetVisability(tableContainer, true);
249
                    instance.LoadEndCalback(tableContainer);
250
                }
251
            };
252
            xmlhttp.open("GET", RequestToUrl(rq), true);
253
            xmlhttp.send();
254
            tail = xmlhttp; //put at tail to can abort later any previous
255
        }
256
        function Init(tableId){
257
            var tContainer = document.getElementById(tableId);
258
            if(iePrior(9)){
259
                TableInitSetColumnsHoverEffect(tContainer, tableId);
260
            }
261
            var tfoot = tContainer.getElementsByTagName("tfoot")[0];
262
            TableHelperProcessPaginationLinks(tfoot);
263
        }
264
        function Draw(tableContainer, d){
265
            TableHelperDraw_Section(tableContainer, d.body);
266
            TableHelperDraw_Section(tableContainer, d.footer, "tfoot");
267
            if(instance.rq !== null){
268
                var hover = document.getElementById(instance.rq.tableId)
269
                            .getElementsByTagName("th")[instance.rq.colNo].lang;
270
                if(hover){
271
                    instance.ColumnHover(tableContainer, instance.rq.colNo);
272
                }
273
            }
274
        }
275
276
        var BuildRequest = TableHelperBuildRequest;
277
        var FilterGetTableId = TableHelperFilterGetTableId;
278
        var GoPageGetNo = TableHelperGoPageGetNo;
279
        var getParent = TableHelperGetParent;
280
        var iePrior = TableHelperIePrior;
281
        var RequestToUrl = TableHelperRequestToUrl;
282
283
        return {
284
            rq: null,
285
            strAsc: String.fromCharCode(9650), //&#9650;
286
            strDesc: String.fromCharCode(9660),//&#9660; 
287
            ReloadData: function(tableId){
288
                var request = {};
289
                BuildRequest(request, tableId, this.strDesc);
290
                LoadData(tableId, request);
291
            },
292
            Filter: function(field){
293
                var crntTableId = FilterGetTableId(field);
294
                if(crntTableId !== null){
295
                    var request = {};
296
                    var exRq = this.rq;
297
                    BuildRequest(request, crntTableId, this.strDesc);
298
                    if(exRq === null ||
299
                        request.filter !== exRq.filter ||
300
                        request.filterBy !== exRq.filterBy
301
                    ){
302
                        LoadData(crntTableId, request);
303
                    }
304
                }
305
            },
306
            GoPage: function(lnk){
307
                var request = {};
308
                var crntTableId = getParent(lnk, "table").getAttribute("id");
309
                BuildRequest(request, crntTableId, this.strDesc);
310
                request.pageNo = GoPageGetNo(lnk, crntTableId);
311
                LoadData(crntTableId, request);
312
                return false;
313
            },
314
            Export: function(lnk, eType){
315
                var request = {};
316
                var crntTableId = getParent(lnk, "table").getAttribute("id");
317
                BuildRequest(request, crntTableId, this.strDesc);
318
                request.exportType = ["CSV", "Excel"].indexOf(eType) >= 0 ?
319
                                        eType : 
320
                                        "csv";
321
                window.open(RequestToUrl(request));
322
                return false;
323
            },
324
            Sort: function(colNo, lnk){
325
                var request = {};
326
                var crntTableId = getParent(lnk, "table").getAttribute("id");
327
                BuildRequest(request, crntTableId, this.strDesc);
328
                if(Math.round(colNo) === request.colNo){
329
                    request.colOrd = (request.colOrd === "asc" ? "desc" : "asc");
330
                }else{
331
                    request.colNo = Math.round(colNo);
332
                    request.colOrd = "asc";
333
                }
334
                LoadData(crntTableId, request);
335
                /* Clear and add new sort arrow */
336
                var headSpans = getParent(lnk, "thead").getElementsByTagName("span");
337
                var length = headSpans.length;
338
                for(var i = 0; i < length; i++){
339
                    headSpans[i].innerHTML = "";
340
                }
341
                lnk.getElementsByTagName("span")[0].innerHTML = (request.colOrd === "desc" ? this.strDesc : this.strAsc);
342
            },
343
            ColumnHover: function(tableContainer, index){
344
                if(!iePrior(9)){
345
                    TableHelperColumnHover.call(this, tableContainer, index);
346
                }
347
            },
348
            LoadEndCalback: function(){},/*Allows override: function(tableId){if(tableId){...}}*/
349
            init: Init
350
        };
351
    }
352
    return {
353
        //Get the Singleton instance if one exists, or create one if it doesn't
354
        getInstance: function(){
355
            if(!instance){
356
                instance = initInstance();
357
            }
358
            return instance;
359
        }
360
    };
361
})();
362
var table = TableSingleton.getInstance();
363